package gnss

import (
	"dgo/goutils/dnet"
	"dgo/goutils/utils"
	"fmt"
	"strings"
	"time"
)

/*
*

	  donefunc
	  	errcode: 1000 尚未连接, 时间太短?
				 1001 连接错误
				 1002 认证失败
				 1003 传输数据异常
	             0   正常
*/
func NtripServTestOnce(connstring string, duration time.Duration, donefunc func(sendsize int, errcode int, errmsg string)) {
	conf := ParseNtripSvrConnectString(connstring)
	if conf == nil {
		if donefunc != nil {
			donefunc(0, -1, "配置错误,测试失败")
		}
	}

	stepFlag := 0 // 5 is done
	var errcode int = 1000
	var errmsg string = ""
	var sendsize int = 0

	tcpclt := dnet.NewTcpClt(conf.Addr)
	tcpclt.AfterConnected = func(sender *dnet.TcpClt) {
		str := "SOURCE " + conf.Pass + " /" + conf.MountPoint + "\r\n"
		str += fmt.Sprintf("User-Agent:NTRIP %s\r\n", "YMS2021")
		str += "\r\n"
		buf := []byte(str)
		stepFlag = 1
		_, err := sender.Write(buf)
		if err != nil {
			stepFlag = -1
			errcode = 1001
			errmsg = fmt.Sprintf("[%s]投递认证头信息异常:%s", utils.NowString(), err.Error())
		}
	}

	tcpclt.BeforeConnect = func(sender *dnet.TcpClt) bool {
		return stepFlag == 0
	}

	tcpclt.ConnectedFail = func(sender *dnet.TcpClt, err error) {
		stepFlag = -1
		errcode = 1001
		errmsg = fmt.Sprintf("连接异常:%s", err.Error())
	}

	tcpclt.AfterRecvBuf = func(sender *dnet.TcpClt, buf []byte) {
		if stepFlag == 1 { // 首次接收
			str := string(buf)
			if strings.Contains(str, "Bad Password") || strings.Contains(str, "Unauthorized") {
				stepFlag = -1
				errcode = 1002
				errmsg = fmt.Sprintf("认证失败:%s", str)
			}
			stepFlag = 2
		}
	}

	go func() {
		if utils.GoFunCatchException {
			defer utils.PanicHandler()
		}

		time.Sleep(time.Millisecond * 100)
		t1 := time.Now()
		for errcode == 1000 {
			if time.Since(t1) > duration {
				stepFlag = 5
				tcpclt.Stop()
				if donefunc != nil {
					if errcode == 1000 && sendsize > 0 {
						errcode = 0
						errmsg = "测试完成"
					}
				}
				break
			}

			if stepFlag == 2 {
				buf := utils.RandBuf(512)
				n, err := tcpclt.Write(buf)
				if err != nil {
					stepFlag = -1
					errcode = 1003
					errmsg = fmt.Sprintf("传递数据异常:%s", err.Error())
				} else {
					sendsize += n
				}
			}
			time.Sleep(time.Millisecond * 200)
		}
		donefunc(sendsize, errcode, errmsg)
	}()
	tcpclt.Start()
}
